<template>
  <div class="map-grid-container">
    <div ref="chartRef" class="chart-container"></div>
    <div class="controls">
      <button @click="toggleGrid" class="control-btn">
        {{ isGridVisible ? "隐藏网格" : "显示网格" }}
      </button>
      <button @click="toggleDensity" class="control-btn">
        {{ isHighDensity ? "降低密度" : "提高密度" }}
      </button>
      <button @click="toggleMap" class="control-btn">
        {{ showMap ? "隐藏地图" : "显示地图" }}
      </button>
      <div class="grid-settings">
        <label>中心点经度: </label>
        <input
          type="number"
          v-model.number="centerLon"
          step="0.5"
          @change="updateGrid"
          min="73"
          max="135"
        />
        <label>中心点纬度: </label>
        <input
          type="number"
          v-model.number="centerLat"
          step="0.5"
          @change="updateGrid"
          min="18"
          max="53"
        />
        <label>网格大小(度): </label>
        <input
          type="number"
          v-model.number="gridSize"
          step="0.5"
          min="0.5"
          @change="updateGrid"
        />
        <label>可见范围(度): </label>
        <input
          type="number"
          v-model.number="visibleRange"
          step="5"
          min="10"
          max="60"
          @change="updateGrid"
        />
        <button @click="toggleAxes" class="control-btn">
          {{ showAxes ? "隐藏经纬度" : "显示经纬度" }}
        </button>
      </div>
      <div class="info">
        <p>当前网格: {{ currentGridCount }}×{{ currentGridCount }}</p>
        <p>线宽: {{ lineWidth }}px</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick, computed } from "vue";
import * as echarts from "echarts";
import chinaJson from "@/assets/china.json"; // 导入中国地图JSON数据

// 组件状态
const chartRef = ref(null);
const chart = ref(null);
const isGridVisible = ref(true);
const isHighDensity = ref(false);
const showAxes = ref(false);
const showMap = ref(true); // 控制地图显示

// 网格配置 - 使用实际经纬度
const centerLon = ref(105); // 中国地理中心经度
const centerLat = ref(35); // 中国地理中心纬度
const gridSize = ref(2); // 网格大小（度）
const visibleRange = ref(30); // 可见范围（度）
const baseGridCount = 100; // 基础网格数量

// 计算当前实际显示的网格数量
const currentGridCount = computed(() => {
  return isHighDensity.value ? baseGridCount : Math.floor(baseGridCount / 5);
});

// 线宽
const lineWidth = computed(() => {
  return isHighDensity.value ? 0.5 : 1;
});

const gridLines = ref([]);
const isChartReady = ref(false);

// 初始化ECharts实例
onMounted(() => {
  nextTick(() => {
    if (chartRef.value) {
      // 初始化图表
      chart.value = echarts.init(chartRef.value);
      // 注册中国地图
      echarts.registerMap("china", chinaJson);
      isChartReady.value = true;

      // 初始化配置
      initChart();

      // 绘制网格
      drawGrid();
    }
  });
});

// 初始化图表配置
const initChart = () => {
  if (!isChartReady.value) return;

  const option = {
    backgroundColor: "#f0f4f7",
    tooltip: {
      trigger: "item",
      formatter: function (params) {
        if (params.seriesType === "lines") {
          return `经纬度: (${params.data[0][0].toFixed(
            2
          )}, ${params.data[0][1].toFixed(2)})`;
        } else if (params.seriesType === "map") {
          return `${params.name}`;
        }
        return "";
      },
    },
    // 地理坐标系配置
    geo: {
      map: "china",
      show: showMap.value,
      roam: false, // 禁止地图缩放和平移
      center: [centerLon.value, centerLat.value],
      zoom: 1.2,
      label: {
        show: false,
        color: "#333",
        fontSize: 12,
      },
      itemStyle: {
        areaColor: "#e6f7ff",
        borderColor: "#91cc75",
        borderWidth: 1,
      },
      emphasis: {
        itemStyle: {
          areaColor: "#b3d9ff",
        },
        label: {
          show: true,
          color: "#000",
        },
      },
    },
    series: [
      // 地图系列
      {
        type: "map",
        map: "china",
        show: showMap.value,
        geoIndex: 0,
        label: {
          show: false,
        },
      },
    ],
  };

  chart.value.setOption(option);
  window.addEventListener("resize", handleResize);
};

// 处理窗口大小变化
const handleResize = () => {
  if (isChartReady.value) {
    chart.value.resize();
  }
};

// 生成网格线数据 - 使用lines系列适配地理坐标系
const generateGridData = () => {
  const lines = [];
  const halfRange = visibleRange.value;

  // 计算网格范围（使用实际经纬度）
  const minLon = centerLon.value - halfRange;
  const maxLon = centerLon.value + halfRange;
  const minLat = centerLat.value - halfRange;
  const maxLat = centerLat.value + halfRange;

  // 计算实际需要绘制的线条数量
  const lonLinesCount = Math.min(
    currentGridCount.value,
    Math.ceil((maxLon - minLon) / gridSize.value)
  );
  const latLinesCount = Math.min(
    currentGridCount.value,
    Math.ceil((maxLat - minLat) / gridSize.value)
  );

  // 绘制纬线（水平线）
  for (let i = 0; i <= latLinesCount; i++) {
    const lat = minLat + (maxLat - minLat) * (i / latLinesCount);
    lines.push({
      type: "lines",
      name: `纬线${i}`,
      coordinateSystem: "geo",
      polyline: true,
      lineStyle: {
        width: lineWidth.value,
        color: i % 10 === 0 ? "rgba(255, 0, 0, 0.7)" : "rgba(255, 0, 0, 0.3)",
        type: i % 10 === 0 ? "solid" : "dashed",
      },
      data: [
        [
          [minLon, lat],
          [maxLon, lat],
        ],
      ],
    });

    // 经纬度标签（可选）
    if (showAxes.value && i % 5 === 0) {
      lines.push({
        type: "scatter",
        name: `纬度标签${i}`,
        coordinateSystem: "geo",
        symbol: "none",
        label: {
          show: true,
          formatter: `${lat.toFixed(1)}°N`,
          fontSize: 10,
          color: "#666",
        },
        data: [[minLon, lat]],
      });
    }
  }

  // 绘制经线（垂直线）
  for (let i = 0; i <= lonLinesCount; i++) {
    const lon = minLon + (maxLon - minLon) * (i / lonLinesCount);
    lines.push({
      type: "lines",
      name: `经线${i}`,
      coordinateSystem: "geo",
      polyline: true,
      lineStyle: {
        width: lineWidth.value,
        color: i % 10 === 0 ? "rgba(0, 0, 255, 0.7)" : "rgba(0, 0, 255, 0.3)",
        type: i % 10 === 0 ? "solid" : "dashed",
      },
      data: [
        [
          [lon, minLat],
          [lon, maxLat],
        ],
      ],
    });

    // 经纬度标签（可选）
    if (showAxes.value && i % 5 === 0) {
      lines.push({
        type: "scatter",
        name: `经度标签${i}`,
        coordinateSystem: "geo",
        symbol: "none",
        label: {
          show: true,
          formatter: `${lon.toFixed(1)}°E`,
          fontSize: 10,
          color: "#666",
        },
        data: [[lon, minLat]],
      });
    }
  }

  return lines;
};

// 绘制网格
const drawGrid = () => {
  if (!isChartReady.value) return;

  gridLines.value = generateGridData();

  const option = chart.value.getOption();

  // 清除之前的网格线系列
  option.series = option.series.filter(
    (series) =>
      series.type === "map" || // 保留地图系列
      !series.name ||
      (!series.name.startsWith("纬线") &&
        !series.name.startsWith("经线") &&
        !series.name.startsWith("纬度标签") &&
        !series.name.startsWith("经度标签"))
  );

  // 添加新的网格线
  if (isGridVisible.value) {
    option.series = [...option.series, ...gridLines.value];
  }

  // 更新地图显示状态和中心点
  option.geo.show = showMap.value;
  option.geo.center = [centerLon.value, centerLat.value];
  option.series[0].show = showMap.value; // 更新地图系列显示状态

  nextTick(() => {
    chart.value.setOption(option, true);
  });
};

// 切换网格显示状态
const toggleGrid = () => {
  isGridVisible.value = !isGridVisible.value;
  drawGrid();
};

// 切换网格密度
const toggleDensity = () => {
  isHighDensity.value = !isHighDensity.value;
  drawGrid();
};

// 切换地图显示状态
const toggleMap = () => {
  showMap.value = !showMap.value;
  drawGrid();
};

// 切换经纬度显示状态
const toggleAxes = () => {
  showAxes.value = !showAxes.value;
  drawGrid();
};

// 更新网格
const updateGrid = () => {
  if (!isChartReady.value) return;
  nextTick(() => drawGrid());
};

// 监听容器大小变化
watch(
  () => chartRef.value?.clientWidth,
  () => {
    if (isChartReady.value) {
      chart.value.resize();
    }
  }
);

// 组件卸载时清理
onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  if (chart.value) {
    chart.value.dispose();
  }
});
</script>

<style scoped>
.map-grid-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}

.chart-container {
  width: 100%;
  height: 100%;
}

.controls {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 10;
  background: rgba(255, 255, 255, 0.9);
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
  max-width: 300px;
}

.control-btn {
  background: #42b983;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  margin-bottom: 10px;
  transition: all 0.3s;
  width: 100%;
}

.control-btn:hover {
  background: #359e75;
  transform: translateY(-2px);
}

.grid-settings {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 15px 0;
}

.grid-settings label {
  font-size: 13px;
  color: #333;
  display: inline-block;
  width: 100px;
}

.grid-settings input {
  width: calc(100% - 110px);
  padding: 6px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.info {
  margin-top: 15px;
  padding-top: 10px;
  border-top: 1px dashed #eee;
  font-size: 12px;
  color: #666;
}

.info p {
  margin: 5px 0;
}
</style>
